﻿using System;
using System.Net;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;

namespace SilverlightFTP
{
    public class DeleteDirectoryCompletedEventArgs : EventArgs
    {
        public DeleteDirectoryCompletedEventArgs(string s)
        {
            message = s;
        }
        private string message;

        public string Message
        {
            get { return message; }
            set { message = value; }
        }
    }
    public class AlreadyExistsEventArgs : EventArgs
    {
        public AlreadyExistsEventArgs(string s)
        {
            message = s;
        }
        private string message;

        public string Message
        {
            get { return message; }
            set { message = value; }
        }
    }
    public class BytesSentCompletedEventArgs : EventArgs
    {
        public BytesSentCompletedEventArgs(int p)
        {
            progress = p;
        }
        private int progress;
        public int Progress
        {
            get { return progress; }
            set { progress = value; }
        }
    }
    public class ListDirectoryCompletedEventArgs : EventArgs
    {
        public ListDirectoryCompletedEventArgs(SilverlightFTP.FTPConnectorRef.FsItem[] a)
        {
            message = a;
        }
        private SilverlightFTP.FTPConnectorRef.FsItem[] message;
        public SilverlightFTP.FTPConnectorRef.FsItem[] Message
        {
            get { return message; }
            set { message = value; }
        }
    }
    public class FileOperationFinishedEventArgs : EventArgs
    {
        public FileOperationFinishedEventArgs(FTPFileOperation f)
        {
            operation = f;
        }
        private FTPFileOperation operation;

        public FTPFileOperation Operation
        {
            get { return operation; }
            set { operation = value; }
        }
    }
    public class DownloadFileOperationFinishedEventArgs : EventArgs
    {
        public DownloadFileOperationFinishedEventArgs(FTPDownloadFileOperation f)
        {
            operation = f;
        }
        private FTPDownloadFileOperation operation;

        public FTPDownloadFileOperation Operation
        {
            get { return operation; }
            set { operation = value; }
        }
    }
    public class DeleteFileOperationFinishedEventArgs : EventArgs
    {
        public DeleteFileOperationFinishedEventArgs(FTPDeleteFileOperation f)
        {
            operation = f;
        }
        private FTPDeleteFileOperation operation;

        public FTPDeleteFileOperation Operation
        {
            get { return operation; }
            set { operation = value; }
        }
    }
    public class ProgramEventArgs : EventArgs
    {
        public ProgramEventArgs(string f,bool t)
        {
            message = f;
            canoperate = t;
        }
        private string message;
        
        public string Message
        {
            get { return message; }
            set { message = value; }
        }
        private bool canoperate;
        public bool CanOperate
        {
            get { return canoperate; }
            set { canoperate = value; }
        }
    }

    public class FTPmanager
    {
        public List<string> BannedItems = new List<string>();
        FTPConnectorRef.FTPWebServiceSoapClient client = new SilverlightFTP.FTPConnectorRef.FTPWebServiceSoapClient();
        public delegate void BanItemDelegate(string f);
        public delegate void UnbanItemDelegate(string f);
        public BanItemDelegate ban;
        public UnbanItemDelegate unban;
        public List<object> OperationPauseBuffer = new List<object>();
        //Удаление директории завершено
        public delegate void DeleteDirectoryCompletedEventHandler(object sender, DeleteDirectoryCompletedEventArgs e);
        public event DeleteDirectoryCompletedEventHandler DeleteDirectoryCompleted;

        //Объект существует
        public delegate void AlreadyExistsEventHandler(object sender, AlreadyExistsEventArgs e);
        public event AlreadyExistsEventHandler AlreadyExists;

        //Список извлечён
        public delegate void ListDirectoryCompletedEventHandler(object sender, ListDirectoryCompletedEventArgs e);
        public event ListDirectoryCompletedEventHandler ListDirectoryCompleted;

        //Кусок файла отправлен
        public delegate void BytesSentCompletedEventHandler(object sender, BytesSentCompletedEventArgs e);
        public event BytesSentCompletedEventHandler BytesSentCompleted;

        //Файл передался
        public delegate void FileOperationFinishedEventHandler(object sender, FileOperationFinishedEventArgs e);
        public event FileOperationFinishedEventHandler FileOperationFinished;

        //Файл передался
        public delegate void DownloadFileOperationFinishedEventHandler(object sender, DownloadFileOperationFinishedEventArgs e);
        public event DownloadFileOperationFinishedEventHandler DownloadFileOperationFinished;

        //Файл положен в очередь
        public delegate void FileOperationEnquedEventHandler(object sender, FileOperationFinishedEventArgs e);
        public event FileOperationEnquedEventHandler FileOperationEnqued;

        //Файл положен в очередь
        public delegate void ProgramMessageHandler(object sender, ProgramEventArgs e);
        public event ProgramMessageHandler ProgramMessage;

        //Файл положен в очередь
        public delegate void DownloadFileOperationEnquedEventHandler(object sender, DownloadFileOperationFinishedEventArgs e);
        public event DownloadFileOperationEnquedEventHandler DownloadFileOperationEnqued;

        //Файл положен в очередь
        public delegate void DeleteFileOperationFinishedEventHandler(object sender, DeleteFileOperationFinishedEventArgs e);
        public event DeleteFileOperationFinishedEventHandler DeleteFileOperationFinished;

        public bool Pause = false;

        private string ftpHost;
        public string FtpHost
        {
            get { return ftpHost; }
            set
            {
                value = value.Trim(new char[] { ' ' });
                if (value.StartsWith("ftp://"))
                {
                    value = value.Replace("ftp://", "");
                    value = "ftp://" + value.Split(new char[] { '/' })[0];
                    ftpHost = value;
                }
                else
                {
                    value = "ftp://" + value.Split(new char[] { '/' })[0];
                    ftpHost = value;
                }
            }
        }
        private string user;
        public string User
        {
            get { return user; }
            set { user = value; }

        }
        private string password;
        public string Password
        {
            get { return password; }
            set { password = value; }
        }
        private string currentPath;
        public string CurrentPath
        {
            get { return currentPath; }
            set { currentPath = value; }
        }
        public string BackPath
        {
            get
            {

                string backpath = CurrentPath.TrimEnd(new char[] { '/' });
                int last = backpath.LastIndexOf('/');
                if (last < 0) last = 0;
                backpath = backpath.Remove(last, backpath.Length - last);
                return backpath;
            }
        }

        public Queue<FTPBasicOperation> Operations = new Queue<FTPBasicOperation>();

        public List<FTPFileOperation> UploadFileOperations = new List<FTPFileOperation>();
        public List<FTPDownloadFileOperation> DownloadFileOperations = new List<FTPDownloadFileOperation>();

        public FTPmanager()
        {
            client.ListDirectoryCompleted += new EventHandler<SilverlightFTP.FTPConnectorRef.ListDirectoryCompletedEventArgs>(client_ListDirectoryCompleted);
            client.deleteDirectoryCompleted += new EventHandler<SilverlightFTP.FTPConnectorRef.deleteDirectoryCompletedEventArgs>(client_deleteDirectoryCompleted);
            client.CreateFolderCompleted += new EventHandler<System.ComponentModel.AsyncCompletedEventArgs>(client_CreateFolderCompleted);
            client.SaveFileCompleted += new EventHandler<System.ComponentModel.AsyncCompletedEventArgs>(client_SaveFileCompleted);
            client.deleteFileCompleted += new EventHandler<SilverlightFTP.FTPConnectorRef.deleteFileCompletedEventArgs>(client_deleteFileCompleted);
            client.CheckFileCompleted += new EventHandler<SilverlightFTP.FTPConnectorRef.CheckFileCompletedEventArgs>(client_CheckFileCompleted);
            client.downloadFileCompleted += new EventHandler<SilverlightFTP.FTPConnectorRef.downloadFileCompletedEventArgs>(client_downloadFileCompleted);
            client.MoveItemCompleted += new EventHandler<System.ComponentModel.AsyncCompletedEventArgs>(client_MoveItemCompleted);
        }

        void client_CreateFolderCompleted(object sender, System.ComponentModel.AsyncCompletedEventArgs e)
        {
            string dest = ((FTPCreateFolderOperation)Operations.Peek()).path;
            Operations.Dequeue();
            if (Operations.Count != 0)
            {
                OperationInitiator();
            }
            Update(dest);
        }
        public void PauseFileOperations()
        {
            Pause = true;
        }
        public void ResumeFileOperations()
        {
            while (OperationPauseBuffer.Count != 0)
            {
                object o = OperationPauseBuffer[0];
                if (o.GetType() == typeof(FTPBytesUploadOperation))
                {
                    if (((FTPBytesUploadOperation)o).path == null)
                    {
                        if (UploadFileOperations.Count != 0)
                        {
                            FileOperationInitiator();
                        }
                    }
                    else if (((FTPBytesUploadOperation)o).datalength != 0)
                    {
                        BytesSentCompletedEventArgs args = new BytesSentCompletedEventArgs(UploadFileOperations[0].Progress);
                        BytesSentCompleted(this, args);
                        Operations.Enqueue((FTPBytesUploadOperation)o);
                        if (Operations.Count == 1)
                        {
                            OperationInitiator();
                        }
                    }
                    else
                    {

                        FileOperationFinished(this, new FileOperationFinishedEventArgs(UploadFileOperations[0]));
                        string dest = UploadFileOperations[0].hostdestination;
                        UnbanItem(UploadFileOperations[0].hostdestination);
                        UploadFileOperations.RemoveAt(0);

                        if (Operations.Count != 0)
                        {
                            OperationInitiator();
                        }
                        if (UploadFileOperations.Count != 0)
                        {
                            FileOperationInitiator();
                        }
                        Update(dest);
                    }
                }
                else if (o.GetType() == typeof(FTPDownloadFileOperation))
                {
                    if (((FTPDownloadFileOperation)o).FileName != null && ((FTPDownloadFileOperation)o).FileName != "")
                    {
                        client.downloadFileAsync(DownloadFileOperations[0].hostdestination, DownloadFileOperations[0].DataRecieved, DownloadFileOperations[0].chunklegth, User, Password);
                    }
                    else
                    {
                        if (DownloadFileOperations.Count != 0)
                        {
                            DownloadFileOperationInitiator();
                        }
                    }
                }
                OperationPauseBuffer.RemoveAt(0);
            }
            Pause = false;
        }
        void client_MoveItemCompleted(object sender, System.ComponentModel.AsyncCompletedEventArgs e)
        {
            string hostdestination = ((FTPRenameOperation)Operations.Peek()).path;
            string newpath = ((FTPRenameOperation)Operations.Peek()).newpath;
            Operations.Dequeue();
            if (Operations.Count != 0) OperationInitiator();
            if (!Update(hostdestination))
            {
                Update(newpath);
            }
        }

        void client_downloadFileCompleted(object sender, SilverlightFTP.FTPConnectorRef.downloadFileCompletedEventArgs e)
        {
            bool end = false;

            if (e.Result == null)
            {
                end = true;
            }
            else
            {
                try
                {
                    DownloadFileOperations[0].fileStream.Write(e.Result, 0, e.Result.Length);
                }
                catch
                {
                    end = true;
                }

            }

            if (end)
            {
                DownloadFileOperations[0].fileStream.Close();
                DownloadFileOperations[0].fileStream.Dispose();
                UnbanItem(DownloadFileOperations[0].hostdestination);
                DownloadFileOperationFinished(this, new DownloadFileOperationFinishedEventArgs(DownloadFileOperations[0]));
                DownloadFileOperations.RemoveAt(0);
                if (Pause)
                {
                    OperationPauseBuffer.Add(new FTPDownloadFileOperation());
                    return;
                }
                if (DownloadFileOperations.Count != 0)
                {
                    DownloadFileOperationInitiator();
                }
            }
            else
            {
                DownloadFileOperations[0].DataRecieved += e.Result.Length;
                if (Pause)
                {
                    OperationPauseBuffer.Add(DownloadFileOperations[0]);
                    return;
                }
                client.downloadFileAsync(DownloadFileOperations[0].hostdestination, DownloadFileOperations[0].DataRecieved, DownloadFileOperations[0].chunklegth, User, Password);
            }
        }

        void client_CheckFileCompleted(object sender, SilverlightFTP.FTPConnectorRef.CheckFileCompletedEventArgs e)
        {
            UploadFileOperations[0].allowed = !e.Result;
            if (e.Result == true)
            {
                AlreadyExistsEventArgs args = new AlreadyExistsEventArgs(UploadFileOperations[0].FileName);
                AlreadyExists(this, args);
            }
            else FileOperationInitiator();
        }

        void client_deleteFileCompleted(object sender, SilverlightFTP.FTPConnectorRef.deleteFileCompletedEventArgs e)
        {
            string dest = ((FTPDeleteFileOperation)Operations.Peek()).path;
            DeleteFileOperationFinishedEventArgs args = new DeleteFileOperationFinishedEventArgs((FTPDeleteFileOperation)Operations.Peek());
            DeleteFileOperationFinished(this, args);
            Operations.Dequeue();
            if (Operations.Count != 0)
            {
                OperationInitiator();
            }
            //Update(dest);
        }
        bool Update(string hostdestination)
        {
            if (System.IO.Path.GetDirectoryName(hostdestination) == System.IO.Path.GetDirectoryName(currentPath))
            {
                ListDirectory(currentPath);
                return true;
            }
            else return false;
        }
        void client_SaveFileCompleted(object sender, System.ComponentModel.AsyncCompletedEventArgs e)
        {

            Operations.Dequeue();
            Int32 bytesRead = 0;
            FTPBytesUploadOperation op = new FTPBytesUploadOperation();
            if (UploadFileOperations[0].FileStream != null)
            {
                bytesRead = UploadFileOperations[0].FileStream.Read(op.buffer, 0, op.buffer.Length);
                op.datalength = bytesRead;
                UploadFileOperations[0].Datasent += op.datalength;
                op.path = UploadFileOperations[0].hostdestination;
            }
            if (Pause)
            {
                OperationPauseBuffer.Add(op);
                if (Operations.Count != 0)
                {
                    OperationInitiator();
                }
                return;
            }
            if (bytesRead != 0)
            {
                BytesSentCompletedEventArgs args = new BytesSentCompletedEventArgs(UploadFileOperations[0].Progress);
                BytesSentCompleted(this, args);
                Operations.Enqueue(op);
                if (Operations.Count != 0)
                {
                    OperationInitiator();
                }
            }
            else
            {

                FileOperationFinished(this, new FileOperationFinishedEventArgs(UploadFileOperations[0]));
                string dest = UploadFileOperations[0].hostdestination;
                UnbanItem(UploadFileOperations[0].hostdestination);
                UploadFileOperations.RemoveAt(0);

                if (Operations.Count != 0)
                {
                    OperationInitiator();
                }
                if (UploadFileOperations.Count != 0)
                {
                    FileOperationInitiator();
                }
                Update(dest);
            }

        }
        public void BanItem(string path)
        {
            BannedItems.Add(path);
            ban(path);
        }
        public void UnbanItem(string path)
        {
            BannedItems.Remove(path);
            unban(path);
        }
        public void ListDirectory(string path)
        {

            ListDirectoryOperation op = new ListDirectoryOperation();
            op.path = path;
            Operations.Enqueue(op);
            if (Operations.Count == 1)
            {
                OperationInitiator();
            }
            //client.ListDirectoryAsync(FtpHost + "/" + path, User, Password);
        }
        public void DownloadFile(Stream fs, string hostdestination, string name, long datalength)
        {
            FTPDownloadFileOperation fop = new FTPDownloadFileOperation();
            fop.FileStream = fs;
            fop.FileName = name;
            fop.hostdestination = hostdestination;
            fop.datalength = datalength;
            fop.DataRecieved = 0;
            BanItem(hostdestination);
            DownloadFileOperations.Add(fop);
            DownloadFileOperationEnqued(this, new DownloadFileOperationFinishedEventArgs(fop));
            //Если очередь файлов была пуста то запускаем её
            if (!Pause)
            {
                if (DownloadFileOperations.Count == 1)
                {
                    DownloadFileOperationInitiator();
                }
            }
            else if (DownloadFileOperations[0].DataRecieved == 0)
            {
                bool contains = false;
                for (int j = 0; j < OperationPauseBuffer.Count; j++)
                {
                    if (OperationPauseBuffer[j].GetType() == typeof(FTPDownloadFileOperation))
                    {
                        OperationPauseBuffer[j] = new FTPDownloadFileOperation();
                        contains = true;
                    }
                }
                if (!contains)
                {
                    OperationPauseBuffer.Add(new FTPDownloadFileOperation());
                }
            }
        }
        public void DownloadFileOperationInitiator()
        {
            //if (DownloadFileOperations[0].allowed)
            //{
            client.downloadFileAsync(DownloadFileOperations[0].hostdestination,
                DownloadFileOperations[0].DataRecieved,
                DownloadFileOperations[0].chunklegth, User, Password);
            //}
            //else client.CheckFileAsync(DownloadFileOperations[0].hostdestination);
        }
        void client_ListDirectoryCompleted(object sender, SilverlightFTP.FTPConnectorRef.ListDirectoryCompletedEventArgs e)
        {
            if (e.Result.Length != 0)
            {
                if (e.Result[0].Size != -1)
                {
                    CurrentPath = e.Result[0].Path + "/";
                    ListDirectoryCompletedEventArgs args = new ListDirectoryCompletedEventArgs(e.Result);
                    ListDirectoryCompleted(this, args);
                }
                else if (e.Result[0].Name == "NameResolutionFailure")
                {
                    ProgramMessage(this, new ProgramEventArgs("Неверно введён адрес", false));
                   
                }
                else if (e.Result[0].Name == "ProtocolError")
                {
                    ProgramMessage(this, new ProgramEventArgs("Неверный пользователь/пароль", false));
                }
            }
            Operations.Dequeue();
            if (Operations.Count != 0)
            {
                OperationInitiator();
            }
        }

        public void DeleteDirectory(string path)
        {
            FTPDeleteDirectoryOperation op = new FTPDeleteDirectoryOperation();
            op.path = path;
            Operations.Enqueue(op);
            if (Operations.Count == 1)
            {
                OperationInitiator();
            }
        }

        public void MoveItem(string hostdestination, string newpath, bool isFolder)
        {
            FTPRenameOperation op = new FTPRenameOperation();
            op.path = hostdestination;
            op.newpath = newpath;
            op.isDirectory = isFolder;
            Operations.Enqueue(op);
            if (Operations.Count == 1)
            {
                OperationInitiator();
            }
        }
        public void RenameItem(string hostdestination, string newname, bool isFolder)
        {
            FTPRenameOperation op = new FTPRenameOperation();
            op.path = hostdestination;
            op.newpath = currentPath + newname;
            if (op.path != op.newpath)
            {
                op.isDirectory = isFolder;
                Operations.Enqueue(op);
                if (Operations.Count == 1)
                {
                    OperationInitiator();
                }
            }
        }


        private void OperationInitiator()
        {
            FTPBasicOperation op = Operations.Peek();
            if (op.GetType() == typeof(FTPCreateFolderOperation))
            {
                client.CreateFolderAsync(((FTPCreateFolderOperation)op).path, User, Password);
            }
            if (op.GetType() == typeof(FTPDeleteDirectoryOperation))
            {
                client.deleteDirectoryAsync(((FTPDeleteDirectoryOperation)op).path, User, Password);
            }
            if (op.GetType() == typeof(FTPDeleteFileOperation))
            {
                client.deleteFileAsync(((FTPDeleteFileOperation)op).path, User, Password);
            }
            if (op.GetType() == typeof(FTPBytesUploadOperation))
            {
                client.SaveFileAsync(((FTPBytesUploadOperation)op).path, ((FTPBytesUploadOperation)op).datalength, ((FTPBytesUploadOperation)op).buffer, User, Password);
            }
            if (op.GetType() == typeof(ListDirectoryOperation))
            {
                client.ListDirectoryAsync(((ListDirectoryOperation)op).path, User, Password);
            }
            if (op.GetType() == typeof(FTPRenameOperation))
            {
                client.MoveItemAsync(((FTPRenameOperation)op).path,
                    ((FTPRenameOperation)op).newpath,
                    ((FTPRenameOperation)op).isDirectory, User, Password);
            }
        }
        public void DeleteFile(string hostdestination)
        {
            FTPDeleteFileOperation op = new FTPDeleteFileOperation();
            op.path = hostdestination;
            Operations.Enqueue(op);
            if (Operations.Count == 1)
            {
                OperationInitiator();
            }
        }
        public void UploadFile(FileInfo file, string hostdestination)
        {
            FTPFileOperation fop = new FTPFileOperation();
            fop.FileStream = file.OpenRead();
            fop.FileName = file.Name;
            fop.hostdestination = hostdestination;
            fop.datalength = fop.FileStream.Length;
            fop.Datasent = 0;
            UploadFileOperations.Add(fop);
            FileOperationEnqued(this, new FileOperationFinishedEventArgs(fop));
            BanItem(hostdestination);
            //Если очередь файлов была пуста то запускаем её
            if (!Pause)
            {
                if (UploadFileOperations.Count == 1)
                {
                    FileOperationInitiator();
                }
            }
            else if (UploadFileOperations[0].Datasent == 0)
            {
                bool contains = false;
                for (int j = 0; j < OperationPauseBuffer.Count; j++)
                {
                    if (OperationPauseBuffer[j].GetType() == typeof(FTPBytesUploadOperation))
                    {
                        OperationPauseBuffer[j] = new FTPBytesUploadOperation(0);
                        contains = true;
                    }
                }
                if (!contains)
                {
                    OperationPauseBuffer.Add(new FTPBytesUploadOperation());
                }
            }
        }
        public void CancelFileOperation(FTPFileOperation f)
        {
            UnbanItem(f.hostdestination);
            int i = UploadFileOperations.IndexOf(f);
            if (i != 0)
            {
                UploadFileOperations.RemoveAt(i);
            }
            else
            {

                UploadFileOperations[0].FileStream = null;
                FTPDeleteFileOperation op = new FTPDeleteFileOperation();
                op.path = f.hostdestination;
                Operations.Enqueue(op);
                if (Operations.Count == 1)
                {
                    OperationInitiator();
                }
                if (Pause)
                {
                    for (int j = 0; j < OperationPauseBuffer.Count; j++)
                    {
                        if (OperationPauseBuffer[j].GetType() == typeof(FTPBytesUploadOperation)) OperationPauseBuffer[j] = new FTPBytesUploadOperation(0);
                    }
                    UploadFileOperations.RemoveAt(i);
                }
            }

        }
        public void CancelDownFileOperation(FTPDownloadFileOperation f)
        {
            UnbanItem(f.hostdestination);
            int i = DownloadFileOperations.IndexOf(f);
            if (i != 0)
            {
                DownloadFileOperations.RemoveAt(i);
            }
            else
            {
                if (Pause)
                {
                    for (int j = 0; j < OperationPauseBuffer.Count; j++)
                    {
                        if (OperationPauseBuffer[j].GetType() == typeof(FTPDownloadFileOperation)) OperationPauseBuffer[j] = new FTPDownloadFileOperation();
                    }
                    DownloadFileOperations.RemoveAt(i);
                    return;
                }
                DownloadFileOperations[0].FileStream.Close();
            }
        }
        public void CancelFileOperationNoDelete(FTPFileOperation f)
        {
            int i = UploadFileOperations.IndexOf(f);
            UploadFileOperations.RemoveAt(i);
        }
        public void FileOperationInitiator()
        {
            if (UploadFileOperations.Count != 0)
            {
                if (UploadFileOperations[0].allowed)
                {
                    BanItem(UploadFileOperations[0].hostdestination);
                    DeleteFile(UploadFileOperations[0].hostdestination);
                    FTPBytesUploadOperation op = new FTPBytesUploadOperation();
                    op.path = UploadFileOperations[0].hostdestination;
                    op.datalength = UploadFileOperations[0].FileStream.Read(op.buffer, 0, op.buffer.Length);
                    Operations.Enqueue(op);
                    if (Operations.Count == 1)
                    {
                        OperationInitiator();
                    }
                }
                else
                {
                    client.CheckFileAsync(UploadFileOperations[0].hostdestination, User, Password);
                }
            }

        }
        public void CreateDirectory(string path)
        {
            FTPCreateFolderOperation op = new FTPCreateFolderOperation();
            op.path = currentPath+path;
            Operations.Enqueue(op);
            if (Operations.Count == 1)
            {
                OperationInitiator();
            }
        }
        private void client_deleteDirectoryCompleted(object sender, SilverlightFTP.FTPConnectorRef.deleteDirectoryCompletedEventArgs e)
        {
            string dest = ((FTPDeleteDirectoryOperation)Operations.Peek()).path;
            Operations.Dequeue();
            DeleteDirectoryCompletedEventArgs args = new DeleteDirectoryCompletedEventArgs(e.Result + Operations.Count.ToString());
            DeleteDirectoryCompleted(this, args);
            if (Operations.Count != 0)
            {
                OperationInitiator();
            }
            Update(dest);
        }
    }
}
